package v1ch07.except;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Scanner;

/**
 * @author Cay Horstmann
 * @version 1.34 2015-08-20
 */
public class ExceptTest {
	public static void main(String[] args) {
		EventQueue.invokeLater(() -> {
			JFrame frame = new ExceptTestFrame();
			frame.setTitle("ExceptTest");
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setVisible(true);
		});
	}
}

/**
 * 带有面板的框架，用于测试各种异常
 */
class ExceptTestFrame extends JFrame {
	public ExceptTestFrame() {
		ExceptTestPanel panel = new ExceptTestPanel();
		add(panel);
		pack();
	}
}

/**
 * 带有单选按钮的面板，用于运行代码片段并研究它们的异常行为
 */
class ExceptTestPanel extends Box {
	private ButtonGroup group;
	private JTextField textField;
	private double[] a = new double[10];
	
	public ExceptTestPanel() {
		super(BoxLayout.Y_AXIS);
		group = new ButtonGroup();
		
		// 为代码片段添加单选按钮
		
		addRadioButton("Integer divide by zero", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				a[1] = 1 / (a.length - a.length);
			}
		});
		
		addRadioButton("Floating point divide by zero", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				a[1] = a[2] / (a[3] - a[3]);
			}
		});
		
		addRadioButton("Array bounds", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				a[1] = a[10];
			}
		});
		
		addRadioButton("Bad cast", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				a = (double[]) event.getSource();
			}
		});
		
		addRadioButton("Null pointer", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				System.out.println(textField.getAction().toString());
			}
		});
		
		addRadioButton("sqrt(-1)", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				a[1] = Math.sqrt(-1);
			}
		});
		
		addRadioButton("Overflow", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				a[1] = 1000 * 1000 * 1000 * 1000;
				int n = (int) a[1];
				System.out.println(n);
			}
		});
		
		addRadioButton("No such file", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				try {
					System.out.println(new Scanner(Paths.get("woozle.txt"), "UTF-8").next());
				} catch (IOException e) {
					textField.setText(e.toString());
				}
			}
		});
		
		addRadioButton("Throw unknown", new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				throw new UnknownError();
			}
		});
		
		// add the text field for exception display
		textField = new JTextField(30);
		add(textField);
	}
	
	/**
	 * 将具有给定侦听器的单选按钮添加到面板。在侦听器的 actionPerformed 方法中捕获任何异常。
	 *
	 * @param s        单选按钮的标签
	 * @param listener 单选按钮的动作监听器
	 */
	private void addRadioButton(String s, ActionListener listener) {
		JRadioButton button = new JRadioButton(s, false) {
			// 按钮调用此方法来触发
			// 动作事件。我们覆盖它以捕获异常
			protected void fireActionPerformed(ActionEvent event) {
				try {
					textField.setText("No exception");
					super.fireActionPerformed(event);
				} catch (Exception e) {
					textField.setText(e.toString());
				}
			}
		};
		
		button.addActionListener(listener);
		add(button);
		group.add(button);
	}
}
